package cn.xuqiudong.rabbitmq.config;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import jakarta.annotation.Resource;

/**
 * 描述:
 *
 * @author Vic.xu
 * @since 2025-02-18 16:40
 */
public class RabbitMqConfig implements ApplicationContextAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(RabbitMqConfig.class);

    @Resource
    private RabbitTemplate rabbitTemplate;
    /**
     * 生产者确认
     * 每个RabbitTemplate只能配置一个RenturnCallback
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        rabbitTemplate.setReturnsCallback((returned) -> {
            LOGGER.info("消息返送失败，应答码:{}, 原因:{},交换机{},路由键:{},消息:{}",
                    returned.getReplyCode(),
                    returned.getReplyText(),
                    returned.getExchange(),
                    returned.getRoutingKey(),
                    returned.getMessage().toString()
                    );
        });
    }

    /**
     * 发送消息，指定消息id，消息ConfirmCallback
     */
    @Test
    public void testPublisherConfirm() {
        String msgId = "";
        // 1. 创建 CorrelationData
        CorrelationData cd = new CorrelationData(msgId);
        // 2 给 Future 添加callback
        /*
        springboot升级后 下面的代码修改为whenComplete
        cd.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>(){
            @Override
            public void onSuccess(CorrelationData.Confirm result) {
                if (result.isAck()) {
                    LOGGER.info("消息发送成功，收到ack");
                } else {
                    LOGGER.info("消息发送失败，收到nack, reason:{}", result.getReason());
                }
            }
            @Override
            public void onFailure(Throwable ex) {
                LOGGER.error("消息发送失败，原因：{}", ex.getMessage());
            }
        });
        */
        cd.getFuture().whenComplete((result, ex) -> {
            if (ex != null) {
                // 处理异常（发送失败）
                LOGGER.error("消息发送失败，原因：{}", ex.getMessage());
            } else {
                // 处理正常结果（ACK/NACK）
                if (result.isAck()) {
                    LOGGER.info("消息发送成功，收到ack");
                } else {
                    LOGGER.info("消息发送失败，收到nack, reason:{}", result.getReason());
                }
            }
        });
        // 3 发送消息
        rabbitTemplate.convertAndSend("exchange.direct", "direct.queue", "hello world", cd);
    }




}
